package com.service.scheduling.task;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.service.dao.constants.ConfigConstants;
import com.service.dao.model.MerchantFilfoxConfig;
import com.service.dao.model.SysConfig;
import com.service.dao.model.SysQuotesIpfx;
import com.service.scheduling.constants.IPFSConstant;
import com.service.scheduling.service.*;
import com.service.scheduling.utils.MemCacheNoTran;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Component
public class MerchantIPFXTask {

	@Autowired
	private MemCacheNoTran memCache;
	@Autowired
	private SysConfigService configService;
	@Autowired
	private CoinsPriceService coinsPriceService;
	@Autowired
	private CoinService coinService;
	@Autowired
	private MerchantFilfoxConfigService merchantFilfoxConfigService;
	@Autowired
	private SysQuotesIpfxService sysQuotesIpfxService;

	private static final BigDecimal T_2_P = new BigDecimal(1024L);

	/**
	 * 每3分钟执行一次更新到缓存
	 */
	@Scheduled(cron = "0 */3 * * * ?")
	public void iPFSInfoTask() {

		SysConfig config = configService.getByName(ConfigConstants.MERCHANT_FIL_FOX_LIST);
		if (ObjectUtils.isEmpty(config)) {
			log.warn("暂无FilFox商家节点列表配置");
			return;
		}
		//获取商家节点列表配置信息
		String[] merchantSymbols = config.getConfValue().split("/");
		if (merchantSymbols.length < 1) {
			log.warn("暂无FilFox商家节点列表配置");
			return;
		}
		List<String> merchantSymbolList = Arrays.asList(merchantSymbols);
		for (String merchantSymbol : merchantSymbolList) {
			//获取商家矿池配置信息
			MerchantFilfoxConfig filFoxConfig = merchantFilfoxConfigService.getOne(new QueryWrapper<MerchantFilfoxConfig>().lambda()
					.eq(MerchantFilfoxConfig::getMerchantSymbol, merchantSymbol));
			if (ObjectUtils.isEmpty(filFoxConfig)) {
				filFoxConfig = new MerchantFilfoxConfig();
				filFoxConfig.setMerchantSymbol(merchantSymbol);
			}
			try {
				Document doc = Jsoup.connect("https://filfox.info/zh/address/" + merchantSymbol).timeout(50000).get();
				Element e = doc.body();
				Elements flexElements = e.getElementsByClass("flex");
				for (Element flex : flexElements) {
					Elements icElements = flex.getElementsByClass("items-center");
					for (Element ic : icElements) {
						Elements jbElements = ic.getElementsByClass("justify-between");
						for (Element jb : jbElements) {
							Elements m3Elements = jb.getElementsByClass("mx-3");
							for (Element m3 : m3Elements) {
								Elements m2Elements = m3.getElementsByClass("mt-2");
								for (Element m2 : m2Elements) {
									Elements m2P = m2.getElementsByTag("p");
									StringBuilder kv = new StringBuilder();
									for (Element p : m2P) {
										kv.append(" ").append(p.text());
										if (kv.toString().contains(IPFSConstant.ORIGINAL_POWER)) {
											BigDecimal originalPower = BigDecimal.ZERO;
											if (kv.toString().contains(" TiB")) {
												String originalPowerVal = originalPowerVal = kv.toString().replace(IPFSConstant.ORIGINAL_POWER, "").replace(" TiB", "");
												originalPowerVal = originalPowerVal.replace(",", "");
												originalPower = new BigDecimal(getNumber(originalPowerVal));
											} else if (kv.toString().contains(" PiB")) {
												String originalPowerVal = originalPowerVal = kv.toString().replace(IPFSConstant.ORIGINAL_POWER, "").replace(" PiB", "");
												originalPowerVal = originalPowerVal.replace(",", "");
												originalPower = new BigDecimal(getNumber(originalPowerVal)).multiply(T_2_P);
											}
											filFoxConfig.setOriginalPower(originalPower);
										}
										if (kv.toString().contains(IPFSConstant.MINING_RATE)) {
											String miningRate = kv.toString().replace(IPFSConstant.MINING_RATE, "").replace(" FIL/TiB", "");
											filFoxConfig.setMiningRate(new BigDecimal(getNumber(miningRate.trim())));
										}
									}
								}
							}
							Elements m2Elements = jb.getElementsByClass("mt-2");
							for (Element m2 : m2Elements) {
								Elements m2P = m2.getElementsByTag("p");
								StringBuilder kv = new StringBuilder();
								for (Element p : m2P) {
									kv.append(p.text());
									if (kv.toString().contains(IPFSConstant.TOTAL_MINING_POWER)) {
										String totalReward = kv.toString().replace(IPFSConstant.TOTAL_MINING_POWER, "").replace(" FIL", "");
										filFoxConfig.setTotalReward(new BigDecimal(getNumber(totalReward)));
										break;
									}
								}
							}
							//抓取排名
							Elements wFull = jb.getElementsByClass("w-full");
							for (Element m2 : wFull) {
								Elements m2P = m2.getElementsByTag("p");
								for (Element p : m2P) {
									StringBuilder kv = new StringBuilder();
									kv.append(p.text());
									if (kv.toString().contains(IPFSConstant.TOTAL_NETWORK_RANK)) {
										String totalReward = kv.toString().replace(IPFSConstant.TOTAL_NETWORK_RANK, "");
										filFoxConfig.setRankNo(Integer.parseInt(getOnlyNum(totalReward)));
										break;
									}
								}
							}
						}
					}
				}
				filFoxConfig.setUpdateTime(new Date());
				merchantFilfoxConfigService.saveOrUpdate(filFoxConfig);
				String json = JSONObject.toJSON(filFoxConfig).toString();
				memCache.setNoExpire(IPFSConstant.MERCHANT_IPFX_INFO_KEY + filFoxConfig.getMerchantSymbol(), json);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	private static String getNumber(String val) {
		String regEx = ",";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(val);
		return m.replaceAll("").trim();
	}

	private static String getOnlyNum(String val) {
		String regEx = "[^0-9]";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(val);
		return m.replaceAll("").trim();
	}
}
